# base_graph.py

from __future__ import division

class base_graph(object):
    '''This graphs multiple sequences of points, possibly in different colors.

    call :meth:`plot` for each sequence of points.

    Call :meth:`reset` to start all over again.
    '''

    def __init__(self):
        self.reset()

    def reset(self):
        self.points = []        # list of (color, sequence of (x, y) pairs)

    def plot(self, points, color = "#ffffff"):
        self.points.append((color, tuple(points)))

    def line(self, start, end, color = "#ffffff"):
        self.points.append((color, (start, end)))

    def calc_scale(self, debug=False):
        r'''Calculates and returns: scale, max_x, max_y.

        Centers the graph on the origin.
        '''
        min_x = min(x for color, points in self.points for x, y in points)
        min_y = min(y for color, points in self.points for x, y in points)
        max_x = max(x for color, points in self.points for x, y in points)
        max_y = max(y for color, points in self.points for x, y in points)
        if debug:
            print "x", min_x, max_x, "y", min_y, max_y

        max_x = max(abs(min_x), abs(max_x))
        max_y = max(abs(min_y), abs(max_y))
        scale_x = self.get_width() / 2.0 / max_x
        scale_y = self.get_height() / 2.0 / max_y
        return min(scale_x, scale_y), max_x, max_y

    def scale_point(self, point, scale, max_x, max_y):
        r'''Scales point.
        '''
        x, y = point
        return (x + max_x) * scale, (max_y - y) * scale

    def scale_points(self, points, scale, max_x, max_y):
        r'''Generates scaled (x, y) pairs from points.
        '''
        for point in points:
            yield self.scale_point(point, scale, max_x, max_y)

